//
//  Register_Vm.swift
//  MikerShop
//
//  Created by eme on 2016/11/24.
//  Copyright © 2016年 eme. All rights reserved.
//

import RxSwift
import Result
import SwiftyJSON
import NetWorkCore
import ModelProtocol
import BrandonCore
/*
 owner:cy
 update:2016年11月24日10:02:06
 info: 注册viewmodel
 */
class Register_Vm {
    
    let validatedPhone: Observable<ValidationResult>
    let validatedMsgCode: Observable<ValidationResult>
    let validatedRegisterCode: Observable<ValidationResult>
    // 表示btn 是否可以点击状态
    let signupEnabled: Observable<Bool>
    // Is signing process in progress
    let signingIn: Observable<Bool>
    private let disposeBag = DisposeBag()
    
    let nextSuccess = PublishSubject<GlShopModel>()
    let error = PublishSubject<MikerError>()
    let sendMsgSuccess = PublishSubject<JSON>()
    private var isValidated:(isOk:Bool ,error:String) = (true,"")
    
    init(input: (
        phone: Observable<String>,
        msgCode: Observable<String>,
        registerCode:Observable<String>,
        nextTaps: Observable<Void>,
        tyTaps: Observable<Bool>,
        getMsgCodeTaps: Observable<Void>
        ),
         validationService: RegisterValidationProtocol
        ) {
        
        validatedPhone = input.phone.map{ phone in
            return validationService.validatePhone(phone)
            }.shareReplay(1)
        
        validatedMsgCode = input.msgCode.map{ msgCode in
            return validationService.validateMsgCode(msgCode)
            }.shareReplay(1)
        validatedRegisterCode = input.registerCode.map{ msgCode in
            return validationService.validateRegisterCode(msgCode)
            }.shareReplay(1)
        let signingIn = ActivityIndicator()
        self.signingIn = signingIn.asObservable()
        
         let usernameAndPassword = Observable.combineLatest(input.phone, input.msgCode,input.registerCode) { ($0, $1,$2) }
        self.signupEnabled = Observable.combineLatest(
            validatedPhone,
            validatedMsgCode,
            signingIn.asObservable(),
            input.tyTaps
        ){ phone, msgCode ,signingIn ,isTy in
            phone.notEmpty && msgCode.notEmpty && !signingIn && isTy
            }
            .distinctUntilChanged()
            .shareReplay(1)
        input.nextTaps
            .filter{ _ in
                return !self.isValidated.isOk
            }.subscribe(onNext: {[unowned self] _ in
                 self.error.onNext(MikerError("文本录入错误", code: 601, message: self.isValidated.error))
            })
            .addDisposableTo(disposeBag)
        
        input.getMsgCodeTaps.withLatestFrom(input.phone)
            .filter{ phone -> Bool in
                let rel = validationService.validatePhone(phone)
                if rel.isValid == false{
                    self.error.onNext(MikerError("获取短信验证码时需要验证手机号", code: 602, message: rel.message))
                }
                return rel.isValid
            }
            .map{ phone in
                
                return UserApi.sendmsg(phone: phone,type: "reg")
                
            }.emeRequestApiForRegJson()
            .subscribe(onNext: {[unowned self] (result) in
                switch result {
                case .success(let data):
                    self.sendMsgSuccess.onNext(data)
                case .failure(let error):
                    self.error.onNext(error)
                }
            })
            .addDisposableTo(disposeBag)
        input.nextTaps.filter{ _ in
            return self.isValidated.isOk
            }.withLatestFrom(usernameAndPassword)
            .map{ phone, msgCode,registerCode in
                return UserApi.regcheck(phone: phone, code: msgCode, type: "reg", aginvitecode: registerCode)
            }
            .emeRequestApiForObj(GlShopModel.self,activityIndicator: signingIn)
            .subscribe(onNext: {[unowned self] (result) in
                switch result {
                case .success(let data):
                    self.nextSuccess.onNext(data)
                case .failure(let error):
                    self.error.onNext(error)
                }
            })
            .addDisposableTo(disposeBag)

        Observable.combineLatest(
            validatedPhone,
            validatedMsgCode,
            validatedRegisterCode
        ) { (item1, item2,item3) -> (isOk:Bool ,error:String) in
            
            if !item1.isValid{
                return (false,item1.message)
            }
            if !item2.isValid{
                return (false,item2.message)
            }
            if !item3.isValid{
                return (false,item3.message)
            }
            return (true,"")
            }
            .subscribe(onNext: { [unowned self] (item) in
                self.isValidated = item
            })
            .addDisposableTo(disposeBag)
        
        
    }
    
}
